from PySide6.QtGui import Qt, QAction
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QTextEdit
from qt_material import apply_stylesheet

from view.message_view import MessageView
from view.error_log_view import ErrorLogView
from tools.adb_tool import AdbTool, AdbThreadWorker
from tools.path_tool import PathTool
from tools.tool_box import get_json_data, validate_ip_port, write_json_data, load_file

# WARNING:root:qt_material must be imported after PySide or PyQt!
# '总计主题样式：26 种！'
_list_themes = ['dark_amber.xml',
                'dark_blue.xml',
                'dark_cyan.xml',
                'dark_lightgreen.xml',
                'dark_pink.xml',
                'dark_purple.xml',
                'dark_red.xml',
                'dark_teal.xml',
                'dark_yellow.xml',
                'light_amber.xml',
                'light_blue.xml',
                'light_blue_500.xml',
                'light_cyan.xml',
                'light_cyan_500.xml',
                'light_lightgreen.xml',
                'light_lightgreen_500.xml',
                'light_orange.xml',
                'light_pink.xml',
                'light_pink_500.xml',
                'light_purple.xml',
                'light_purple_500.xml',
                'light_red.xml',
                'light_red_500.xml',
                'light_teal.xml',
                'light_teal_500.xml',
                'light_yellow.xml']

_high_color = {
    "红色": "red",
    "蓝色": "blue",
    "绿色": "green",
    "黄色": "yellow",
    "橙色": "orange",
    "青色": "cyan",
    "紫色": "purple",
    "白色": "white",
    "黑色": "black",
    "粉色": "pink",
    "灰色": "grey"
}


class AdbLogView:
    def __init__(self, _app):
        self.__app = _app
        self.__path_tool = None
        self.__adb_tool = None
        self.__thread_worker = None
        self.__should_stop = None
        self.__adb_log_view = None
        self.__error_log_view = None
        self.__addr_comboBox = None
        self.__log_textEdit = None
        self.__cmd_lineEdit = None
        self.__color_menu = None
        self.__high_menu = None
        self.__high_color = None
        self.__extra = None
        self.__config_json = None
        self.message = MessageView()
        self.should_stop_thread = None
        self.mouse_press_pos = None
        self.__init_view()
        self.__init_event()
        self.__init_error_log_view()

    # noinspection PyUnresolvedReferences
    def __init_view(self):
        """
        初始化界面展示内容
        """
        self.__path_tool = PathTool()
        self.__adb_log_view = QUiLoader().load(self.__path_tool.get_ui_path("adb_log_view"))
        self.__log_textEdit = self.__adb_log_view.log_textEdit
        self.__addr_comboBox = self.__adb_log_view.addr_comboBox
        self.__addr_comboBox.setEditText("127.0.0.1:5555")
        self.__log_textEdit.setLineWrapMode(QTextEdit.NoWrap)  # 禁用自动换行（核心设置）
        self.__log_textEdit.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)  # 强制显示水平滚动条（确保长文本可滚动查看）
        self.__init_config()
        self.__init_menuBar()
        self.__init_panel()
        self.__init_high_color()

    def __init_error_log_view(self):
        self.__error_log_view = ErrorLogView(self.__adb_tool.get_error_log, self.__adb_tool.clear_error_log)

    def __init_config(self):
        """
        初始化读取config文件数据
        """
        self.__config_json = get_json_data(self.__path_tool.get_ui_path("config"))

    def __init_panel(self):
        """
        初始化窗口主题
        """
        self.__extra = get_json_data(self.__path_tool.get_ui_path("extra"))
        text = self.__config_json["theme"]
        if text:
            apply_stylesheet(self.__app, theme=text, extra=self.__extra)
        else:
            apply_stylesheet(self.__app, theme=_list_themes[0], extra=self.__extra)

    def __init_style(self):
        """应用样式"""
        style = load_file(self.__path_tool.get_ui_path("Style"))
        self.__adb_log_view.setStyleSheet(style)

    def __init_event(self):
        """
        初始化事件绑定
        """
        self.__adb_log_view.show_log_button.clicked.connect(self.devices_event)
        self.__adb_log_view.save_log_button.clicked.connect(self.save_log_event)
        self.__adb_log_view.clear_log_button.clicked.connect(self.clear_log_event)
        self.__adb_log_view.skill_adb_server_button.clicked.connect(self.skill_abd_server_event)
        self.__adb_log_view.clear_adb_log_button.clicked.connect(self.clear_adb_log_event)
        self.__adb_log_view.restart_adb_button.clicked.connect(self.restart_adb_event)
        self.__adb_log_view.pause_log_button.clicked.connect(self.pause_log_event)
        self.__adb_log_view.error_log_button.clicked.connect(self.error_log_event)
        self.__color_menu.triggered[QAction].connect(self.color_menu_event)
        self.__high_menu.triggered[QAction].connect(self.high_color_event)
        self.__adb_tool = AdbTool()
        self.__adb_tool.pause_log_setText = self.__adb_log_view.pause_log_button.setText
        self.__adb_tool.show_log_setText = self.__adb_log_view.show_log_button.setText

    def __init_menuBar(self):
        """
        初始化主题菜单
        """
        self.__color_menu = self.__adb_log_view.color_menu
        self.__high_menu = self.__adb_log_view.high_menu
        dark = self.__color_menu.addMenu('dark（黑暗主题）')
        light = self.__color_menu.addMenu('light（亮色主题）')
        for item in _list_themes:
            if 'dark' in item:
                dark.addAction(item)
            else:
                light.addAction(item)
        for key in _high_color.keys():
            self.__high_menu.addAction(key)

    def __init_high_color(self):
        """
        初始化高亮颜色
        """
        self.__high_menu = self.__adb_log_view.high_menu
        self.__high_color = _high_color[self.__config_json["high_color"]]

    def writ_config_json(self, key, value):
        """
        写入config配置文件
        :param key: 需要修改的键
        :param value: 需要修改的值
        """
        self.__config_json[key] = value
        write_json_data(self.__path_tool.get_ui_path("config"), self.__config_json)

    def start_thread_worker(self):
        """
        启动线程
        """
        self.stop_thread_worker()
        self.__thread_worker = AdbThreadWorker(self.__adb_tool.show_log)
        self.__thread_worker.log_signal.connect(self.print_log)
        self.__thread_worker.start()

    def stop_thread_worker(self):
        """
        停止执行打印日志线程
        """
        if not self.__thread_worker:  # 如果线程为空
            return
        if not self.__thread_worker.isRunning:  # 如果线程没有在运行中
            return
        self.__adb_tool.quit = True
        self.__adb_tool.disconnect()
        self.__thread_worker.quit()

    def __print(self, ms):
        """
        日志打印
        :param ms: 需要打印的内容
        """
        self.__log_textEdit.append(ms)

    def print_log(self, ms):
        """
        通过 log_textEdit 追加 字信息
        :param ms: 需要追加的文字
        """
        ms_str = ms[1].strip()
        if ms[0] == 1:
            # 在行尾插入富文本
            ms_str = f"<span style=\"color:{self.__high_color}\";>{ms_str}</span>\n"
        self.__print(ms_str)

    def high_color_event(self, menu):
        """
        高亮设置响应事件
        """
        text = menu.text()
        self.__high_color = _high_color[text]
        self.writ_config_json("high_color", text)

    def color_menu_event(self, menu):
        """
        主题颜色响应事件
        """
        text = menu.text()
        if text:
            apply_stylesheet(self.__app, theme=text, extra=self.__extra)
        else:
            apply_stylesheet(self.__app, theme=_list_themes[0], extra=self.__extra)
        self.writ_config_json("theme", text)

    # def to_end_event(self):
    #     """
    #     打印框打印时，输入定位到行尾
    #     """
    #     self.__log_textEdit.moveCursor(QTextCursor.End)

    def error_log_event(self):
        """
        展示错误日志
        """
        self.__error_log_view.ShowDialog()

    def devices_event(self):
        """
        连接设备并进行日志打印
        """
        # 判断设备码是否正确
        adb_ip = self.__addr_comboBox.currentText()
        # if not validate_ip_port(adb_ip):
        #     for i in range(3):
        #         self.__print(
        #             f"！！！！！！！！警告！！！！！！！！\n设备地址错误【{adb_ip}】，请输入正确地址，地址格式如:127.0.0.1:5555")
        #         return
        # 判断是否无设备正在连接中
        if not self.__adb_tool.is_connected():
            # self.log("【【【【【【没有连接中的设备】】】】】】")
            self.show_log_event(adb_ip)
        else:
            self.__print(f"【【【【【【有正在连接的设备,设备adb_ip：{self.__adb_tool.get_current_adb_ip()}】】】】】】")
            # 已经连接的判断是否为相同设备
            if self.__adb_tool.is_same_adb_ip(adb_ip):
                # 如果是相同设备，判断线程状态，线程正在执行中的话，无需重复执行
                # self.log("【【【【【【相同设备】】】】】】")
                if self.__thread_worker.isRunning():
                    # self.log(f"【【【【【【设备adb_ip：{self.__adb_tool.get_current_adb_ip()}，线程正在运行中】】】】】】")
                    self.stop_thread_worker()
                    self.__print(f"【【【【【【设备adb_ip：{self.__adb_tool.get_current_adb_ip()}，线程已停止】】】】】】")
                    return
                else:
                    # 相同设备，线程没有执行的话，执行线程
                    self.__print(
                        f"【【【【【【设备adb_ip：{self.__adb_tool.get_current_adb_ip()}，线程没在运行，从新运行线程】】】】】】")
                    self.show_log_event(adb_ip)
            else:
                # 不同设备时，判断线程状态，线程正在执行中的话需要先停下当前线程，再从新执行线程
                # self.log("【【【【【【不同设备】】】】】】")
                if self.__thread_worker.isRunning():
                    self.__print(
                        f"【【【【【【设备adb_ip：{self.__adb_tool.get_current_adb_ip()}，线程正在运行，需要关闭线程】】】】】】")
                    self.__print(f"【【【【【【设备adb_ip：{self.__adb_tool.get_current_adb_ip()}，关闭正在运行线程】】】】】】")
                    self.stop_thread_worker()
                self.__print("【【【【【【开始运行新线程】】】】】】")
                self.show_log_event(adb_ip)

    def show_log_event(self, adb_ip):
        """
        通过 log_textEdit 输出 adb 日志
        :param adb_ip: 设备码
        """
        # 设置需要连接的设备 adb_ip
        self.__adb_tool.set_current_adb_ip(adb_ip)
        try:
            self.start_thread_worker()
            self.stop_thread_worker()
        except Exception as e:
            self.__print(f"show_log_event 发生错误: {str(e)}")
            self.stop_thread_worker()

    def restart_adb_event(self):
        """
        关闭ADB进程后重新启动ADB服务
        """
        self.__print("【【【【【【关闭ADB进程后重新启动ADB服务】】】】】】")
        self.stop_thread_worker()
        output = self.__adb_tool.restart_adb()
        if output:
            self.__print(output)
        self.__print("【【【【【【执行完毕】】】】】】")

    def skill_abd_server_event(self):
        """
        关闭ADB服务
        """
        self.__print("【【【【【【关闭ADB服务】】】】】】")
        output = self.__adb_tool.skill_adb_server()
        if output:
            self.__print(output)
        self.__print("【【【【【【执行完毕】】】】】】")

    def clear_adb_log_event(self):
        """
        清空当adb所有日志
        """
        if self.__thread_worker and self.__thread_worker.isRunning():
            key, ms = self.__adb_tool.clear_log()
            if not key:
                self.print_log((1, f"{ms}"))
            else:
                self.__print(ms)
        else:
            self.print_log((1, "【【【【【【没有连接中的adb设备，无法清除adb日志】】】】】】"))

    def pause_log_event(self):
        """
        暂停日志打印
        """
        if self.__thread_worker and self.__thread_worker.isRunning():
            if self.__adb_tool.get_should_stop():
                self.__adb_tool.restart_log()
                self.__print("【【【【【【【【已开始日志打印】】】】】】】】")
            else:
                self.__adb_tool.pause_log()
                self.__print("【【【【【【【【已暂停日志打印】】】】】】】】")

    def save_log_event(self):
        """
        保存当前窗口所有日志内容到桌面
        """
        # self.__print("保存当前窗口所有日志内容到桌面")
        text = self.__log_textEdit.toPlainText()
        if not text:
            self.__print("【【【【【【【【窗口当前无内容】】】】】】】】")
            return
        try:
            Desktop_path = self.__adb_tool.get_desktop_path()
            with open(Desktop_path, "w", encoding="utf-8") as f:
                f.write(text)
            self.__print(f"日志文件已保存：{Desktop_path}")
        except Exception as e:
            for i in range(3):
                self.print_log((1, f"【【【【【【【【！！！日志文件保存失败！！！】】】】】】】】"))
            self.__print(e)
            self.message.show_message(e)

    def clear_log_event(self):
        """
        清空当前窗口展示的所有日志
        """
        self.__log_textEdit.clear()

    def show(self):
        """
        展示adb_log_view窗口
        """
        self.__adb_log_view.show()

# if __name__ == '__main__':
#     try:
#         app = QApplication(sys.argv)
#         adb_log_view = AdbLogView(app)
#         adb_log_view.show()
#         sys.exit(app.exec())
#     except Exception as e:
#         message = MessageView()
#         message.show_message(e)
